package com.knife.common.tree.utils;

import com.knife.common.exception.CommonException;
import com.knife.common.tree.annotations.KnifeTreeParentId;
import com.knife.common.tree.constant.KnifeRootType;
import com.knife.common.tree.dto.ElementUiTree;
import org.apache.commons.lang3.reflect.FieldUtils;
import org.springframework.util.CollectionUtils;

import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

/**
 * @author tianhao.luo@hand-china.com
 * @version 1.0
 * @date 2022年06月06日 星期一 8:05 下午
 * @description
 * @since 1.0
 */
public class KnifeTreeUtil {

    public static <T, A extends Annotation> Field getAnnotationField(Class<T> tClass, Class<A> annotationClass) {
        Field[] fieldsWithAnnotation = FieldUtils.getFieldsWithAnnotation(tClass, annotationClass);
        if (Objects.isNull(fieldsWithAnnotation) || fieldsWithAnnotation.length > 1) {
            throw new CommonException(annotationClass.getSimpleName() + "为空或者作用于多个属性");
        }
        return fieldsWithAnnotation[0];
    }

    public static <E> List<E> getRootList(Field treeIdField, Field treeParentIdField, List<E> dataList) throws IllegalAccessException {
        KnifeTreeParentId knifeTreeParentIdFieldAnnotation = treeParentIdField.getAnnotation(KnifeTreeParentId.class);
        KnifeRootType knifeRootType = knifeTreeParentIdFieldAnnotation.rootType();
        List<E> rootList = new ArrayList<>();
        if (KnifeRootType.EQUAL == knifeRootType) {
            for (E data : dataList) {
                Object treeParentIdObj = FieldUtils.readField(treeParentIdField, data, true);
                Object treeIdObj = FieldUtils.readField(treeIdField, data, true);
                if (Objects.equals(treeIdObj, treeParentIdObj)) {
                    rootList.add(data);
                }
            }
            // 假如没有找到根节点
        } else if (KnifeRootType.NULL == knifeRootType) {
            for (E data : dataList) {
                Object treeParentIdObj = FieldUtils.readField(treeParentIdField, data, true);
                if (treeParentIdObj == null) {
                    rootList.add(data);
                }
            }
        }
        return rootList;
    }

    public static <E,V> List<E> getRootList(Field treeIdField, List<E> dataList,V rootValue) throws IllegalAccessException {
        List<E> rootList = new ArrayList<>();
        for (E data : dataList) {
            Object treeIdObj = FieldUtils.readField(treeIdField, data, true);
            if (Objects.equals(treeIdObj, rootValue)) {
                rootList.add(data);
            }
        }
        return rootList;
    }

    public static <E,V> E getRoot(Field treeIdField,  List<E> dataList,V rootValue) throws IllegalAccessException {
        for (E data : dataList) {
            Object treeIdObj = FieldUtils.readField(treeIdField, data, true);
            if (Objects.equals(treeIdObj, rootValue)) {
                return data;
            }
        }
        return null;
    }


    public static <E> E getRoot(Field treeIdField, Field treeParentIdField, List<E> dataList) throws IllegalAccessException {
        KnifeTreeParentId knifeTreeParentIdFieldAnnotation = treeParentIdField.getAnnotation(KnifeTreeParentId.class);
        KnifeRootType knifeRootType = knifeTreeParentIdFieldAnnotation.rootType();
        if (KnifeRootType.EQUAL == knifeRootType) {
            for (E data : dataList) {
                Object treeParentIdObj = FieldUtils.readField(treeParentIdField, data, true);
                Object treeIdObj = FieldUtils.readField(treeIdField, data, true);
                if (Objects.equals(treeIdObj, treeParentIdObj)) {
                    return data;
                }
            }
        } else if (KnifeRootType.NULL == knifeRootType) {
            for (E data : dataList) {
                Object treeParentIdObj = FieldUtils.readField(treeParentIdField, data, true);
                if (treeParentIdObj == null) {
                    return data;
                }
            }
        }
        return null;
    }

    /**
     * 将非叶子节点设置为不可选，叶子节点可选
     */
    public static void recursionFinalElementUiTree(List<? extends ElementUiTree> elementUiTrees) {
        for (ElementUiTree elementUiTree : elementUiTrees) {
            if (CollectionUtils.isEmpty(elementUiTree.getChildren())) {
                elementUiTree.setDisabled(false);
            } else {
                elementUiTree.setDisabled(true);
            }
            recursionFinalElementUiTree(elementUiTree.getChildren());
        }
    }
}
